/**
 * created by 小卷毛, 2019-09-18 018
 * Copyright (c) 2019, 416143467@qq.com All Rights Reserved.
 * #                   *********                            #
 * #                  ************                          #
 * #                  *************                         #
 * #                 **  ***********                        #
 * #                ***  ****** *****                       #
 * #                *** *******   ****                      #
 * #               ***  ********** ****                     #
 * #              ****  *********** ****                    #
 * #            *****   ***********  *****                  #
 * #           ******   *** ********   *****                #
 * #           *****   ***   ********   ******              #
 * #          ******   ***  ***********   ******            #
 * #         ******   **** **************  ******           #
 * #        *******  ********************* *******          #
 * #        *******  ******************************         #
 * #       *******  ****** ***************** *******        #
 * #       *******  ****** ****** *********   ******        #
 * #       *******    **  ******   ******     ******        #
 * #       *******        ******    *****     *****         #
 * #        ******        *****     *****     ****          #
 * #         *****        ****      *****     ***           #
 * #          *****       ***        ***      *             #
 * #            **       ****        ****                   #
 */
package com.aifeng.viewmodel

import androidx.lifecycle.LifecycleOwner
import com.aifeng.common_ui.event.BaseViewEvent
import com.aifeng.utils.*
import com.lzg.extend.BaseResponse
import com.lzg.extend.jackson.JacksonConvert
import com.lzg.okrx.RxSingleHelper
import com.lzg.okrx.adapter.FlowableBody
import com.lzy.okgo.OkGo
import com.lzy.okgo.model.HttpParams
import com.lzy.okgo.utils.OkLogger
import io.reactivex.disposables.CompositeDisposable
import org.json.JSONObject
import java.io.Serializable

/**
 * viewModel 基类
 */
open class BaseViewModel : BaseViewEvent() {

    protected val mDisposables by lazy { CompositeDisposable() }

    protected fun getParams(vararg params: Pair<String, Any>): HttpParams {
        val data = JSONObject().apply { params.forEach { put(it.first, it.second) } }.toString()
        val timestamp = System.currentTimeMillis()
        val builder =
            StringBuilder().append("cs_core")
                .append("timestamp").append(timestamp)
                .append("plat").append("android")
                .append("v").append(mVersion)
                .append("data").append(data)
                .append("cs_core")
                .toString()

        OkLogger.i("[params]", data)

        return HttpParams().apply {
            put("data", data)
            put("plat", "android")
            put("sign", MD5.md5(builder))
            put("timestamp", timestamp)
            put("v", mVersion)
        }
    }

    protected fun getParams(params: Map<String, Any>): HttpParams {
        val data = JSONObject().apply { params.forEach { put(it.key, it.value) } }.toString()
        val timestamp = System.currentTimeMillis()
        val builder =
            StringBuilder().append("cs_core")
                .append("timestamp").append(timestamp)
                .append("plat").append("android")
                .append("v").append(mVersion)
                .append("data").append(data)
                .append("cs_core")
                .toString()

        OkLogger.i("[params]", data)

        return HttpParams().apply {
            put("data", data)
            put("plat", "android")
            put("sign", MD5.md5(builder))
            put("timestamp", timestamp)
            put("v", mVersion)
        }
    }

    /**
     * 公用的请求json字符串的方法
     * 使用方式：
     *    request(
     *        requestUrl = 请求url,
     *        params = *arrayOf(..),
     *        onResult = {}
     *    )
     */
    fun request(
        requestUrl: String,
        vararg params: Pair<String, Any>,
        onResult: (String) -> Unit = {}
    ) {
        mDisposables.add(
            RxSingleHelper.requestString(
                url = requestUrl,
                params = getParams(*params)
            )
                .compose(applySchedulers())
                .doOnSubscribe { showLoading() }
                .doFinally { dismissLoading() }
                .subscribeByNoError(
                    event = this,
                    onSuccess = { onResult.invoke(it) }
                )
        )
    }

    /**
     * 公用的请求并解析实体类的方法
     * 使用方式：
     *    requestModel(
     *        requestUrl = 请求url,
     *        params = *arrayOf(..),
     *        onSuccess = {},
     *        onFinally = {}
     *    )
     */
    fun <T : Serializable> requestModel(
        requestUrl: String,
        vararg params: Pair<String, Any>,
        onSuccess: (T) -> Unit = {},
        onFinally: () -> Unit = {}
    ) {
        mDisposables.add(
            OkGo.post<BaseResponse<T>>(requestUrl)
                .params(getParams(*params))
                .converter(object : JacksonConvert<BaseResponse<T>>() {})
                .adapt(FlowableBody())
                .compose(applyFlowableSchedulers())
                .map { it.data }
                .subscribeByFinally(
                    event = this,
                    onSuccess = { onSuccess(it) },
                    onFinally = { onFinally() }
                )
        )
    }

    override fun onDestroy(owner: LifecycleOwner) {
        super.onDestroy(owner)
        mDisposables.clear()
    }

    companion object {
        var mVersion = ""
    }

}